﻿using System;
using System.Data;

public class SlabsTable
{
    #region member variables - private
    //getters
    private int SlabId = 0;
    private int rowCount = 0;
    private int colCount = 0;

    //internal
    private string ROperator = "";
    private string COperator = "";

    //storage
    private DataTable flatDt;
    #endregion

    #region getters
    //for 1d, there is one extra row
    public int getRowCount()
    {
        if (colCount <= 1) return rowCount + 1;
        else return rowCount;
    }
    public int getColumnCount() { return colCount; }
    public int getSlabId() { return SlabId; }
    public DataTable getFlatMatrix() { return flatDt; }
    public string getCOper() { return COperator; }
    public string getROper() { return ROperator; }
    #endregion

    #region constuctor - new matrix
    public SlabsTable(int si, int rows, string rop, int columns = 1, string cop = "")
    {
        //set dimensions 
        SlabId = si;
        rowCount = rows;
        colCount = columns;
        ROperator = rop;
        COperator = cop;

        createFlat();
    }

    private void createFlat()
    {
        flatDt = new DataTable();

        //create columns
        flatDt.Columns.Add("SlabId");
        flatDt.Columns.Add("RowNo");
        flatDt.Columns.Add("ColumnNo");
        flatDt.Columns.Add("Value");

        //populate datatable with default values
        int rows = (colCount > 1 ? rowCount : rowCount -1 );
        for (int i = 0; i <= rows; i++)
        {
            for (int j = 0; j <= colCount; j++)
            {
                DataRow dr = flatDt.NewRow();
                dr["SlabID"] = SlabId;
                dr["RowNo"] = i;
                dr["ColumnNo"] = j;
                dr["Value"] = 0;
                flatDt.Rows.Add(dr);
            }
        }
        flatDt.AcceptChanges();

        //save it in db
        updateMatrix2DB(flatDt);
    }
    #endregion

    #region constructor - existing matrix
    public SlabsTable(int si)
    {
        SlabId = si;
        RetrieveDimension();
        RetrieveDBValues();
    }

    private void RetrieveDimension()
    {
        string rowCmd = "Select Max(RowNo) from SlabValues where SlabId = '" + SlabId.ToString() + "'";
        string colCmd = "Select Max(ColumnNo) from SlabValues where SlabId = '" + SlabId.ToString() + "'";
        string ropCmd = "Select ROperator from Slabs where RowNo = '" + SlabId.ToString() + "'";
        string copCmd = "Select COperator from Slabs where RowNo = '" + SlabId.ToString() + "'";

        string rows = DataBaseMethods.ExecuteScalar(rowCmd);
        string cols = DataBaseMethods.ExecuteScalar(colCmd);
        string rop = DataBaseMethods.ExecuteScalar(ropCmd);
        string cop = DataBaseMethods.ExecuteScalar(copCmd);

        try
        {
            //get dimension
            rowCount = Convert.ToInt32(rows);
            colCount = Convert.ToInt32(cols);
            //get operators
            ROperator = rop;
            COperator = cop;
        }
        catch (Exception)
        {
            throw new Exception("Slab does not exist.");
        }

        if ((rowCount < 1) || (colCount < 1))
            throw new Exception("Invalid Slab Dimensions");

        return;
    }

    private void RetrieveDBValues()
    {
        //select command
        string selectCmd = "Select SlabId, RowNo, ColumnNo, Value from SlabValues where SlabId = '" + SlabId.ToString() + "' Order By RowNo, ColumnNo ";

        //get slab values - flat structure
        flatDt = DataBaseMethods.ExecuteSelectQuery(selectCmd);
    }
    #endregion

    #region update operations
    public void updateMatrix2DB(DataTable dtb)
    {
        //delete old values first and then add these
        string deleteCommand2 = "DELETE FROM SlabValues WHERE SlabId = '" + SlabId.ToString() + "'";
        DataBaseMethods.ExecuteNonQuery(deleteCommand2);

        DataBaseMethods.uploadDT2DB(dtb, "SlabValues");
        flatDt = dtb;
    }
    #endregion
}
